package com.runjian.rundo.iot.agent.iec104.parser.frame.monitoring.process;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ByteUtil;
import com.runjian.rundo.iot.agent.iec104.parser.frame.InfoElement;
import com.runjian.rundo.iot.agent.iec104.parser.frame.monitoring.base.BaseMonitoringFrame;
import lombok.Getter;
import lombok.Setter;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

/**
 * | 字段               | 字节数 | 示例值（十六进制） | 说明                                                                 |
 * |--------------------|--------|-------------------|----------------------------------------------------------------------|
 * | **APCI 部分**      |        |                   |                                                                      |
 * | 启动字符           | 1      | `68`              | 固定起始符，标识报文开始[3,5](@ref)                                      |
 * | APDU长度           | 1      | `0x1B`            | 当前字节后的总字节数（示例中为27字节）[3,5](@ref)                       |
 * | 控制域（I帧）       | 4      | `00 00 00 00`     | 发送/接收序号（低字节在前），用于确认传输序列[3,4](@ref)                 |
 * | **ASDU 部分**      |        |                   |                                                                      |
 * | 类型标识           | 1      | `CE` (206)        | 标识为累计量短浮点数（M_IT_NB_1）[3,5](@ref)                            |
 * | 可变结构限定词     | 1      | `83`              | SQ=1（地址连续），低7位表示信息体数量（示例中为3个）[4,7](@ref)         |
 * | 传输原因           | 2      | `14 00`           | 原因码（0x14=响应总召唤），小端格式[3,5](@ref)                          |
 * | 公共地址           | 2      | `01 00`           | 子站地址（小端格式，示例中为1）[3,5](@ref)                              |
 * | **信息体部分**     |        |                   |                                                                      |
 * | 信息体地址（首地址）| 3      | `01 41 00`        | 3字节小端地址（实际地址：`0x004101`）[3,5,7](@ref)                     |
 * | 数据值1            | 4      | `00 00 80 43`     | 短浮点数（小端格式，示例值256.0）[5,7](@ref)                            |
 * | 品质描述词 | 1      | `00`        |                      |
 * | 数据值2            | 4      | `00 00 00 44`     | 短浮点数（示例值512.0）                                               |
 * | 数据值3            | 4      | `00 00 80 44`     | 短浮点数（示例值768.0）                                               |
 *
 * @author byw
 * @date 2025/05/21
 */
@Getter
@Setter
public class M_IT_NA_1 extends BaseMonitoringFrame {

	@Override
	public void analysisInfo(byte[] msg) {
		if (Boolean.TRUE.equals(this.getSq())) {
			// 地址连续
			int baseAddress = ByteUtil.bytesToInt(new byte[]{msg[12], msg[13], msg[14], 0x00});
			for (int i = 0; i < this.getNumber(); i++) {
				byte[] valueBytes = ArrayUtil.sub(msg, 15 + i * 5, 19 + i * 5);
				ByteBuffer littleEndianBuffer = ByteBuffer.wrap(valueBytes);
				short value = littleEndianBuffer.order(ByteOrder.LITTLE_ENDIAN).getShort();
				this.addInfoElement(InfoElement.<Short>builder().address(baseAddress + i)
						.qds((short) (msg[19 + i * 4] & 0xff))
						.value(value).build());
			}
		} else {
			// SQ=0非连续模式：逐个解析地址+数据
			//  解析信息体（索引14开始）
			for (int i = 0; i < this.getNumber(); i++) {
				int address = ByteUtil.bytesToInt(new byte[]{msg[12 + (8 * i)], msg[13 + (8 * i)], msg[14 + (8 * i)], 0x00});
				byte[] valueBytes = ArrayUtil.sub(msg, 15 + i * 8, 19 + i * 8);
				ByteBuffer littleEndianBuffer = ByteBuffer.wrap(valueBytes);
				short value = littleEndianBuffer.order(ByteOrder.LITTLE_ENDIAN).getShort();
				this.addInfoElement(InfoElement.<Short>builder()
						.address(address)
						.value(value).build());
			}
		}
	}
}
